﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System
{
    /// <summary>
    /// Random随机数帮助类
    /// </summary>
    public static class RandomHelper
    {
        /// <summary>
        /// 生成中文随即字符串
        /// </summary>
        /// <param name="strlength"></param>
        /// <returns></returns>
        public static string GetRandomChinese(int strlength)
        {
            // 获取GB2312编码页（表） 
            Encoding gb = Encoding.GetEncoding("gb2312");

            object[] bytes = CreateRegionCode(strlength);

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < strlength; i++)
            {
                string temp = gb.GetString((byte[])Convert.ChangeType(bytes[i], typeof(byte[])));
                sb.Append(temp);
            }

            return sb.ToString();
        }

        /// <summary>
        /// 随机数
        /// </summary>
        /// <param name="maxValue">最大值</param>
        /// <returns></returns>
        public static decimal RandomNext(int maxValue)
        {
            var rand = new Random(Guid.NewGuid().GetHashCode());
            var result = rand.Next(maxValue);
            return result;
        }

        /// <summary>  
        /// 获取指定长度的纯数字随机数字串  
        /// </summary>  
        /// <param name="intlong">数字串长度</param>  
        /// <returns>纯数字随机数字串</returns>  
        public static string GetRandomNum(int intlong)
        {
            StringBuilder w = new StringBuilder(string.Empty);
            var rand = new Random(Guid.NewGuid().GetHashCode());
            for (int i = 0; i < intlong; i++)
            {
                w.Append(rand.Next(10));
            }
            return w.ToString();
        }

        /// <summary>  
        /// 获取指定长度的随机字符串  
        /// </summary>  
        /// <param name="pwdlen">随机字符串的长度</param>  
        /// <returns>随机产生的字符串</returns>  
        public static string GetRandomString(int pwdlen)
        {
            return GetRandomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_*", pwdlen);
        }

        /// <summary>  
        /// 获取指定长度的纯字母随机字符串  
        /// </summary>  
        /// <param name="pwdlen">数字串长度</param>  
        /// <returns>纯字母随机字符串</returns>  
        public static string GetRandWord(int pwdlen)
        {
            return GetRandomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", pwdlen);
        }

        public static string GetRandChinese(int pwdlen)
        {
            string str = "将进酒君不见黄河之水天上来奔流到海不复回君不见高堂明镜悲白发朝如青丝暮成雪人生得意须尽欢莫使金樽空对月天生我材必有用千金散尽还复来烹羊宰牛且为乐会须一饮三百杯岑夫子丹丘生将进酒杯莫停与君歌一曲请君为我倾耳听钟鼓馔玉不足贵但愿长醉不复醒古来圣贤皆寂寞惟有饮者留其名陈王昔时宴平乐斗酒十千恣欢谑主人何为言少钱径须沽取对君酌五花马千金裘呼儿将出换美酒与尔同销万古愁噫吁嚱危乎高哉蜀道之难难于上青天蚕丛及鱼凫开国何茫然尔来四万八千岁不与秦塞通人烟西当太白有鸟道可以横绝峨眉巅地崩山摧壮士死然后天梯石栈相钩连上有六龙回日之高标下有冲波逆折之回川黄鹤之飞尚不得过猿猱欲度愁攀援攀援一作攀缘青泥何盘盘百步九折萦岩峦扪参历井仰胁息以手抚膺坐长叹问君西游何时还？畏途巉岩不可攀但见悲鸟号古木雄飞雌从绕林间又闻子规啼夜月愁空山蜀道之难难于上青天使人听此凋朱颜连峰去天不盈尺枯松倒挂倚绝壁飞湍瀑流争喧豗砯崖转石万壑雷其险也如此嗟尔远道之人胡为乎来哉也如此一作也若此剑阁峥嵘而崔嵬一夫当关万夫莫开所守或匪亲化为狼与豺朝避猛虎夕避长蛇磨牙吮血杀人如麻锦城虽云乐不如早还家蜀道之难难于上青天侧身西望长咨嗟";
            return GetRandomString(str, pwdlen);

        }

        /// <summary>  
        /// 获取指定长度和字符的随机字符串  
        /// 通过调用 Random 类的 Next() 方法，先获得一个大于或等于 0 而小于 pwdchars 长度的整数  
        /// 以该数作为索引值，从可用字符串中随机取字符，以指定的密码长度为循环次数  
        /// 依次连接取得的字符，最后即得到所需的随机密码串了。  
        /// </summary>  
        /// <param name="pwdchars">随机字符串里包含的字符</param>  
        /// <param name="pwdlen">随机字符串的长度</param>  
        /// <returns>随机产生的字符串</returns>  
        public static string GetRandomString(string pwdchars, int pwdlen)
        {
            StringBuilder tmpstr = new StringBuilder();
            int randNum;
            var rand = new Random(Guid.NewGuid().GetHashCode());
            for (int i = 0; i < pwdlen; i++)
            {
                randNum = rand.Next(pwdchars.Length);
                tmpstr.Append(pwdchars[randNum]);
            }

            return tmpstr.ToString();
        }
        /// <summary>
        /// 随机生成中文姓名
        /// </summary>
        /// <returns></returns>
        public static string GenName()
        {
            string[] _firstName = new string[]{  "白","毕","卞","蔡","曹","岑","常","车","陈","成" ,"程","池","邓","丁","范","方","樊","费","冯","符"
           ,"傅","甘","高","葛","龚","古","关","郭","韩","何" ,"贺","洪","侯","胡","华","黄","霍","姬","简","江"
           ,"姜","蒋","金","康","柯","孔","赖","郎","乐","雷" ,"黎","李","连","廉","梁","廖","林","凌","刘","柳"
           ,"龙","卢","鲁","陆","路","吕","罗","骆","马","梅" ,"孟","莫","母","穆","倪","宁","欧","区","潘","彭"
           ,"蒲","皮","齐","戚","钱","强","秦","丘","邱","饶" ,"任","沈","盛","施","石","时","史","司徒","苏","孙"
           ,"谭","汤","唐","陶","田","童","涂","王","危","韦" ,"卫","魏","温","文","翁","巫","邬","吴","伍","武"
           ,"席","夏","萧","谢","辛","邢","徐","许","薛","严" ,"颜","杨","叶","易","殷","尤","于","余","俞","虞"
           ,"元","袁","岳","云","曾","詹","张","章","赵","郑" ,"钟","周","邹","朱","褚","庄","卓" };
            string _lastName = "是一种优秀的数据打包和数据交换的形式在当今大行于天下如果没有听说过它的大名那可真是孤陋寡闻了用描述数据的优势显而易见它具有结构简单便于人和机器阅读的双重功效并弥补了关系型数据对客观世界中真实数据描述能力的不足组织根据技术领域的需要制定出了的格式规范并相应的建立了描述模型简称各种流行的";

            Random rnd = new Random(System.DateTime.Now.Millisecond);
            string txtName = string.Format("{0}{1}{2}",
                _firstName[rnd.Next(_firstName.Length - 1)], 
                _lastName.Substring(rnd.Next(0, _lastName.Length - 1), 1),
                _lastName.Substring(rnd.Next(0, _lastName.Length - 1), 1));

            return txtName;
        }

        /** 
        此函数在汉字编码范围内随机创建含两个元素的十六进制字节数组，每个字节数组代表一个汉字，并将 
        四个字节数组存储在object数组中。 
        参数：strlength，代表需要产生的汉字个数 
        **/
        private static object[] CreateRegionCode(int strlength)
        {
            //定义一个字符串数组储存汉字编码的组成元素 
            string[] rBase = new String[16] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

            Random rnd = new Random();

            //定义一个object数组用来 
            object[] bytes = new object[strlength];

            /*
             每循环一次产生一个含两个元素的十六进制字节数组，并将其放入bytes数组中 
             每个汉字有四个区位码组成 
             区位码第1位和区位码第2位作为字节数组第一个元素 
             区位码第3位和区位码第4位作为字节数组第二个元素 
            */
            for (int i = 0; i < strlength; i++)
            {
                //区位码第1位 
                int r1 = rnd.Next(11, 14);
                string str_r1 = rBase[r1].Trim();

                //区位码第2位 
                rnd = new Random(r1 * unchecked((int)DateTime.Now.Ticks) + i); // 更换随机数发生器的 种子避免产生重复值 
                int r2;
                if (r1 == 13)
                {
                    r2 = rnd.Next(0, 7);
                }
                else
                {
                    r2 = rnd.Next(0, 16);
                }
                string str_r2 = rBase[r2].Trim();

                //区位码第3位 
                rnd = new Random(r2 * unchecked((int)DateTime.Now.Ticks) + i);
                int r3 = rnd.Next(10, 16);
                string str_r3 = rBase[r3].Trim();

                //区位码第4位 
                rnd = new Random(r3 * unchecked((int)DateTime.Now.Ticks) + i);
                int r4;
                if (r3 == 10)
                {
                    r4 = rnd.Next(1, 16);
                }
                else if (r3 == 15)
                {
                    r4 = rnd.Next(0, 15);
                }
                else
                {
                    r4 = rnd.Next(0, 16);
                }
                string str_r4 = rBase[r4].Trim();

                // 定义两个字节变量存储产生的随机汉字区位码 
                byte byte1 = Convert.ToByte(str_r1 + str_r2, 16);
                byte byte2 = Convert.ToByte(str_r3 + str_r4, 16);
                // 将两个字节变量存储在字节数组中 
                byte[] str_r = new byte[] { byte1, byte2 };

                // 将产生的一个汉字的字节数组放入object数组中 
                bytes.SetValue(str_r, i);
            }

            return bytes;
        }

    }
}